//
//  FormatableDatePicker.m
//  Rich
//
//  Created by Kenny Chen on 13/9/1.
//  Copyright (c) 2013年 Kenny Chen. All rights reserved.
//
// TODO: Support tap scroll on year and day column
//

#import "RichCore.h"
#import "FormatableDatePicker.h"

#define CalendarUnitFlag (NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekCalendarUnit | NSDayCalendarUnit)

@implementation FormatableDatePicker

@synthesize date;
@synthesize timeZone;
@synthesize dateFormat;
@synthesize maximumYear;
@synthesize minimumYear;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        dateFormater = [[NSDateFormatter alloc] init];
        dateComponents = [[NSDateComponents alloc] init];
        date = nil;
        maximumYear = 2200;
        minimumYear = 1900;
        dateFormat = RichLocaleString(@"Y-M-D");
        dateComponentOrder[0] = FormatableDatePickerComponentYear;
        dateComponentOrder[1] = FormatableDatePickerComponentMonth;
        dateComponentOrder[2] = FormatableDatePickerComponentDay;
        font = [[UIFont boldSystemFontOfSize:22] retain];
        monthComponentSize = 65;
        
        self.tag = 0;
        self.delegate = self;
        self.showsSelectionIndicator = YES;
        self.timeZone = [NSTimeZone defaultTimeZone];
        
        [self updateDateComponentOrder];
    }
    return self;
}

- (void)dealloc
{
    self.delegate = nil;
    [font release];
    [dateComponents release];
    [dateFormater release];
    [super dealloc];
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/

- (void)updateDateComponentOrder
{
    NSArray *tableComponentsStr = [dateFormat componentsSeparatedByString:@"-"];
    int i;
    
    if ([tableComponentsStr count] == 0 || [tableComponentsStr count] > 3) {
        // Invalid date format, set to default
        dateComponentOrder[0] = FormatableDatePickerComponentYear;
        dateComponentOrder[1] = FormatableDatePickerComponentMonth;
        dateComponentOrder[2] = FormatableDatePickerComponentDay;
        return;
    }
    
    for (i = 0; i < [tableComponentsStr count]; i++) {
        if ([(NSString *)[tableComponentsStr objectAtIndex:i] isEqualToString:@"Y"])
            dateComponentOrder[i] = FormatableDatePickerComponentYear;
        else if ([(NSString *)[tableComponentsStr objectAtIndex:i] isEqualToString:@"M"])
            dateComponentOrder[i] = FormatableDatePickerComponentMonth;
        else if ([(NSString *)[tableComponentsStr objectAtIndex:i] isEqualToString:@"D"])
            dateComponentOrder[i] = FormatableDatePickerComponentDay;
        else {
            // Invalid date format, set to default
            dateComponentOrder[0] = FormatableDatePickerComponentYear;
            dateComponentOrder[1] = FormatableDatePickerComponentMonth;
            dateComponentOrder[2] = FormatableDatePickerComponentDay;
            return;
        }
    }
    
    for (; i < 3; i++)
        dateComponentOrder[i] = FormatableDatePickerComponentNone;
}

- (void)updateMonthComponentSize
{
    CGSize stringSize;
    
    for (NSString *monthString in dateFormater.monthSymbols) {
        stringSize = [monthString sizeWithFont:font];
        stringSize.width += 16;
        
        if (monthComponentSize < stringSize.width)
            monthComponentSize = stringSize.width;
    }
}

- (void)setDate:(NSDate *)_date
{
    NSInteger comp;
    NSDateComponents *_components;
    NSDateComponents *firstDateComponents;
    
    if (date) [date release];
    
    date = [_date copy];
    
    _components = [[NSCalendar currentCalendar] components:CalendarUnitFlag
                                                  fromDate:date];
    _components.timeZone = timeZone;
    
    dateComponents.year = _components.year;
    dateComponents.month = _components.month;
    dateComponents.day = _components.day;
    dateComponents.timeZone = timeZone;
    
    // Calculate number of week of month
    firstDateComponents = [[NSCalendar currentCalendar] components:CalendarUnitFlag
                                                          fromDate:[DateHelper firstDayOfMonthForDate:_date]];
    firstDateComponents.timeZone = timeZone;
    
    dateComponents.week = dateComponents.week - firstDateComponents.week + 1;
    
    // Select current tableComponents of given date
    for (comp = 0; comp < [self numberOfComponents]; comp++) {
        if (dateComponentOrder[comp] == FormatableDatePickerComponentYear)
            [self selectRow:dateComponents.year - minimumYear inComponent:comp animated:NO];
        else if (dateComponentOrder[comp] == FormatableDatePickerComponentMonth)
            [self selectRow:dateComponents.month - 1 inComponent:comp animated:NO];
        else
            [self selectRow:dateComponents.day - 1 inComponent:comp animated:NO];
    }
    
    [self reloadAllComponents];
}

- (void)setDateFormat:(NSString *)_dateFormat
{
    NSInteger comp;
    dateFormat = _dateFormat;
    [self updateDateComponentOrder];
    [self reloadAllComponents];
    
    // Select current tableComponents of given date
    for (comp = 0; comp < [self numberOfComponents]; comp++) {
        if (dateComponentOrder[comp] == FormatableDatePickerComponentYear)
            [self selectRow:dateComponents.year - minimumYear inComponent:comp animated:NO];
        else if (dateComponentOrder[comp] == FormatableDatePickerComponentMonth)
            [self selectRow:dateComponents.month - 1 inComponent:comp animated:NO];
        else
            [self selectRow:dateComponents.day - 1 inComponent:comp animated:NO];
    }
}

#pragma mark - Picker view delegates

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    if (dateComponentOrder[2] != FormatableDatePickerComponentNone)
        return 3;
    else if (dateComponentOrder[1] != FormatableDatePickerComponentNone)
        return 2;
    else
        return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)tableComponents
{
    if (dateComponentOrder[tableComponents] == FormatableDatePickerComponentYear)
        return maximumYear - minimumYear;
    else if (dateComponentOrder[tableComponents] == FormatableDatePickerComponentMonth)
        return [dateFormater.monthSymbols count];
    else {
        NSCalendar *cal = [NSCalendar currentCalendar];
        NSDateComponents * comps = [cal components:NSUIntegerMax fromDate:date];
        [comps setYear:dateComponents.year];
        [comps setMonth:dateComponents.month];
        [comps setDay:15];
        NSRange rng = [cal rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:[cal dateFromComponents:comps]];
        return rng.length;
    }
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)tableComponents
{
    if (dateComponentOrder[tableComponents] == FormatableDatePickerComponentYear)
        return [NSString stringWithFormat:@"%ld", 1900 + row];
    else if (dateComponentOrder[tableComponents] == FormatableDatePickerComponentMonth)
        return [dateFormater.monthSymbols objectAtIndex:row];
    else
        return [NSString stringWithFormat:@"%ld", row + 1];
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)tableComponents
{
    if (dateComponentOrder[tableComponents] == FormatableDatePickerComponentYear)
        dateComponents.year = row + minimumYear;
    else if (dateComponentOrder[tableComponents] == FormatableDatePickerComponentMonth)
        dateComponents.month = row + 1;
    else
        dateComponents.day = row + 1;
    
    if (date) [date release];
    
    date = [[[NSCalendar currentCalendar] dateFromComponents:dateComponents] copy];
    
    [pickerView reloadAllComponents];
}


- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)tableComponents
{
    if (dateComponentOrder[tableComponents] == FormatableDatePickerComponentYear)
        return 65.0f;
    else if (dateComponentOrder[tableComponents] == FormatableDatePickerComponentMonth) {
        [self updateMonthComponentSize];
        return monthComponentSize;
    }
    else
        return 60.0f;
}

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)tableComponents reusingView:(UIView *)view
{
    pickerView.tag = row;
    UILabel *label = (UILabel *)view;
    CGFloat width = [self pickerView:self widthForComponent:tableComponents];
    CGRect frame = CGRectMake(0.0f, 0.0f, width, 45.0f);
    
    if (!label) {
        label = [[[UILabel alloc] initWithFrame:frame] autorelease];
        label.font = font;
        label.textAlignment = NSTextAlignmentCenter;
        label.backgroundColor = [UIColor clearColor];
    }
    
    label.text = [self pickerView:pickerView titleForRow:row forComponent:tableComponents];

    return label;
}

@end
